package com.backend.system.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNode;
import cn.hutool.core.lang.tree.TreeNodeConfig;
import cn.hutool.core.lang.tree.TreeUtil;
import com.backend.system.beans.menu.ListMenuByRoleReq;
import com.backend.system.beans.menu.ListMenuByRoleVO;
import com.backend.system.dao.entity.Menu;
import com.baomidou.mybatisplus.extension.service.IService;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * <p>
 * 菜单表 服务类
 * </p>
 *
 * @author backend-manage
 * @since 2024-04-02
 */
public interface IMenuService extends IService<Menu> {

    /**
     * 获取所有菜单，树形展示
     *
     * @return 菜单信息
     */
    List<Tree<String>> getAllMenus();

    /**
     * 通过角色ID获取角色拥有的菜单列表
     *
     * @param roleId 角色ID
     * @return 菜单列表
     */
    List<Menu> getMenusByRoleId(Long roleId);

    /**
     * 通过角色ID获取所有菜单列表
     *
     * @param roleId 角色ID
     * @return 菜单列表
     */
    List<Menu> getAllMenusByRoleId(Long roleId);

    default List<Tree<String>> menuToTree(List<Menu> menus) {
        // 构建node列表
        List<TreeNode<String>> nodeList = CollUtil.newArrayList();
        for (Menu menu : menus) {
            TreeNode<String> treeNode = new TreeNode<>(menu.getId().toString(), menu.getParentId().toString(), menu.getName(), menu.getWeight());
            Map<String, Object> extra = new HashMap<>(8);
            extra.put("icon", menu.getIcon());
            extra.put("component", menu.getComponent());
            extra.put("path", menu.getPath());
            extra.put("url", menu.getUrl());
            extra.put("weight", menu.getWeight());
            if (Objects.nonNull(menu.getSelected())) {
                extra.put("selected", menu.getSelected());
            }
            treeNode.setExtra(extra);
            nodeList.add(treeNode);
        }

        //配置
        TreeNodeConfig treeNodeConfig = new TreeNodeConfig();
        // 最大递归深度
        treeNodeConfig.setDeep(3);
        // 0表示最顶层的id是0
        return TreeUtil.build(nodeList, "0", treeNodeConfig,
                (treeNode, tree) -> {
                    tree.setId(treeNode.getId());
                    tree.setParentId(treeNode.getParentId());
                    tree.setWeight(treeNode.getWeight());
                    tree.setName(treeNode.getName());
                    // 扩展属性
                    Map<String, Object> extra = treeNode.getExtra();
                    if (CollUtil.isNotEmpty(extra)) {
                        tree.putAll(extra);
                    }
                });
    }

    /**
     * 按角色查询全部未禁用菜单（标识已拥有、未拥有）
     *
     * @param req 请求入参
     * @return 菜单信息
     */
    ListMenuByRoleVO listMenuByRole(ListMenuByRoleReq req);
}
